using System;
using SmartPeople.Framework.SecuritySpace;

namespace SmartPeople.Framework.SecuritySpace
{
    public sealed class SecuritySecuredDocuments : ISecuritySecuredDocuments
    {
        private ISecuritySecuredDocumentsProvider provider;
        private ISecuritySpace securitySpace;
        private ISecuritySecuredType defaultDocumentSecuredType;

        /// <summary>
        /// Gets the type of the default document secured.
        /// </summary>
        /// <value>The type of the default document secured.</value>
        private ISecuritySecuredType DefaultDocumentSecuredType
        {
            get
            {
                if (defaultDocumentSecuredType == null)
                    throw new ArgumentNullException("DefaultDocumentSecuredType",
                                                    "Please call SetDefaultPathType first!");
                return defaultDocumentSecuredType;
            }
        }


        public void SetDefaultPathType(ISecuritySecuredType securedType)
        {
            Provider.SetDefaultPathType(securedType);
        }

        /// <summary>
        /// Sets the type of the default document.
        /// </summary>
        /// <param name="securedType">Type of the secured.</param>
        public void SetDefaultDocumentType(ISecuritySecuredType securedType)
        {
            defaultDocumentSecuredType = securedType;
        }


        public SecuritySecuredDocuments(ISecuritySpace securitySpace, ISecuritySecuredDocumentsProvider provider, ISecuritySecuredType defaultPathType)
        {
            if (securitySpace == null) throw new ArgumentNullException("securitySpace cannot be null!");
            if (provider == null) throw new ArgumentNullException("provider cannot be null!");
            if (defaultPathType == null) throw new ArgumentNullException("defaultPathType cannot be null!");
                        this.securitySpace = securitySpace;
            this.provider = provider;
            Provider.SetDefaultPathType(defaultPathType);
            
            CreateRoot(defaultPathType);
        }

        private ISecuritySecuredDocumentsProvider Provider
        {
            get { return provider; }
            set { provider = value; }
        }

        public int Count
        {
            get { return Provider.Count; }
        }


        public ISecuritySecuredDocument CreatePath(string path)
        {
            return CreatePath(path, "");
        }


        public ISecuritySecuredDocument CreatePath(string path, ISecuritySecuredType securedType)
        {
            return CreatePath(path, securedType, DefaultDocumentSecuredType);
        }


        public ISecuritySecuredDocument CreatePath(string path, string pathSecuredTypeName)
        {
            ISecuritySecuredType securedType = securitySpace.SecuredTypes.GetSecuredType(pathSecuredTypeName);
            return CreatePath(path, securedType, DefaultDocumentSecuredType);
        }


        public ISecuritySecuredDocument CreatePath(string path, string pathSecuredTypeName,
                                                   string defaultSecuredTypeName)
        {
            ISecuritySecuredType securedType = securitySpace.SecuredTypes.GetSecuredType(pathSecuredTypeName);
            return CreatePath(path, securedType, defaultDocumentSecuredType);
        }


        public ISecuritySecuredDocument CreatePath(string path, ISecuritySecuredType securedType,
                                                   ISecuritySecuredType defaultSecuredType)
        {
            return Provider.CreatePath(path, securedType, defaultSecuredType);
        }

        public ISecuritySecuredDocument CreatePath(string pathName, ISecuritySecuredType securedType,
                                                   ISecuritySecuredType defaultChildSecuredType,
                                                   ISecuritySecuredDocument parentSecuredDocument)
        {
            //throw new NotImplementedException();
            return Provider.CreatePath(pathName, securedType, defaultChildSecuredType, parentSecuredDocument);
        }


        public ISecuritySecuredDocument CreateDocument(string path, string documentName)
        {
            ISecuritySecuredDocument parentDocument = CreatePath(path);
            return CreatePath(path + "/" + documentName,parentDocument.DefaultChildSecuredType,DefaultDocumentSecuredType);
        }


        public ISecuritySecuredDocument GetDocument(string path)
        {
            return Provider.GetDocument(path);
        }


        public ISecuritySecuredDocument GetKnownParentPath(string path)
        {
            return Provider.GetKnownParentPath(path);
        }


        public void UpdatePath(ISecuritySecuredDocument securityPath)
        {
            //throw new NotImplementedException();
             Provider.UpdatePath(securityPath);
        }


        public ISecuritySecuredDocument CreateDocument(string path, string documentName, string securedTypeName)
        {
            return CreatePath(path + "/" + documentName, securedTypeName);
        }


        public void Clear()
        {
            Provider.Clear();
        }


        private void CreateRoot(ISecuritySecuredType securedType)
        {
            ISecuritySecuredDocument rootDocument = null;
            try
            {
                rootDocument = GetDocument("/");
            }
            catch{}

            if (rootDocument == null)
                Provider.CreatePath("/", securedType, securedType,null);
                
        }
    }
}